<template>
    <div class="register_container" @keyup.enter="register" tabindex="0">
        <div class="layer1"></div>
        <div class="layer2"></div>
        <div class="layer3"></div>
        <div class="layer4"></div>
        <div class="layer5"></div>
        <div class="layer6"></div>

        <el-form class="register_form" :model="registerData" :rules="rules" ref="registerForms">
            <h1>注&nbsp;&nbsp;册</h1>
            <h2>请注册专属于您的账号</h2>
            <el-form-item prop="username">
                <el-input
                    :prefix-icon="User"
                    v-model="registerData.username"
                    placeholder="请输入含有5-10位数字或字母的用户名"
                ></el-input>
            </el-form-item>
            <el-form-item prop="password">
                <el-input
                    type="password"
                    :prefix-icon="Lock"
                    v-model="registerData.password"
                    show-password
                    placeholder="请输入密码，长度为6-15位"
                ></el-input>
            </el-form-item>
            <el-form-item prop="confirmPassword">
                <el-input
                    type="password"
                    :prefix-icon="Lock"
                    v-model="registerData.confirmPassword"
                    show-password
                    placeholder="请再次输入密码进行确认"
                ></el-input>
            </el-form-item>
            <el-form-item prop="realname">
                <el-input
                    :prefix-icon="Tickets"
                    v-model="registerData.realname"
                    placeholder="请输入您的昵称"
                ></el-input>
            </el-form-item>
            <el-form-item>
                <el-button
                    :loading="loading"
                    class="register_btn"
                    type="primary"
                    size="default"
                    @click="register"
                >
                    注册
                </el-button>
            </el-form-item>
            <el-form-item class="to-login">
                <span class="login" @click="toLogin">已有账号？前往登录</span>
            </el-form-item>
        </el-form>
    </div>
</template>

<script setup lang="ts">
import { User, Lock, Tickets } from '@element-plus/icons-vue'
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
//引入用户相关的小仓库
import useUserStore from '@/store/modules/user'
import type { registerFormData } from '@/api/user/type'

//获取用户相关的小仓库
let userStore = useUserStore()
//获取路由器
let $router = useRouter()
//获取el-form组件
let registerForms = ref()
//定义变量控制按钮加载状态
let loading = ref<boolean>(false)
//收集账号与密码的数据
let registerData = reactive<registerFormData>({
    username: '',
    password: '',
    confirmPassword: '',
    realname: '',
})

//注册按钮回调
const register = async () => {
    //保证全部表单校验通过再发请求
    await registerForms.value.validate()
    //加载效果，开始加载
    loading.value = true
    try {
        //保证注册成功
        await userStore.userRegister(registerData)
        //编程式导航跳转到登录页
        $router.push({ path: '/login' })
        //注册成功的提示信息
        ElMessage({
            type: 'success',
            message: '注册成功',
        })
        //注册成功加载效果消失
        loading.value = false
    } catch (error) {
        //注册识别加载效果消失
        loading.value = false
        //注册失败的提示信息
        ElMessage({
            type: 'error',
            message: (error as Error).message,
        })
    }
}
//自定义校验规则函数
const validatorUserName = (_rule: any, value: any, callback: any) => {
    //校验长度
    if (value.length < 5 || value.length > 10) {
        return callback(new Error('用户名长度至少为5位，至多为10位'))
    }
    //校验是否只包含英文和阿拉伯数字
    const regex = /^[A-Za-z0-9]+$/
    if (!regex.test(value)) {
        return callback(new Error('用户名只能包含英文字符和阿拉伯数字'))
    }

    callback() //通过校验
}
const validatorPassword = (_rule: any, value: any, callback: any) => {
    //rule即为数组校验规则对象，value为表单元素文本内容，符合条件callback放行通过，否则注入错误信息
    if (value.length < 6 || value.length > 15) {
        callback(new Error('密码长度至少为6位，至多为15位'))
    }
    //校验是否只包含英文和阿拉伯数字
    const regex = /^[A-Za-z0-9_-]+$/
    if (!regex.test(value)) {
        return callback(new Error('密码只能包含英文字符、阿拉伯数字和特殊字符'))
    }

    callback() //通过校验
}
const checkPassword = (_rule: any, value: any, callback: any) => {
    //rule即为数组校验规则对象，value为表单元素文本内容，符合条件callback放行通过，否则注入错误信息
    if (value === registerData.password) {
        callback()
    } else {
        callback(new Error('密码不一致'))
    }
}
const validatorRealname = (_rule: any, value: any, callback: any) => {
    //rule即为数组校验规则对象，value为表单元素文本内容，符合条件callback放行通过，否则注入错误信息
    if (value.length) {
        callback()
    } else {
        callback(new Error('用户呢称不能为空'))
    }
}
//定义表单检验配置对象
const rules = {
    username: [{ trigger: 'change', validator: validatorUserName }],
    password: [{ trigger: 'change', validator: validatorPassword }],
    confirmPassword: [{ trigger: 'change', validator: checkPassword }],
    realname: [{ trigger: 'change', validator: validatorRealname }],
}

//前往登录页
const toLogin = () => {
    //编程式导航跳转到登录页
    $router.push({ path: '/login' })
}
</script>

<style scoped lang="scss">
@function getShadows($n, $size) {
    $shadows:
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 0.3)} rgba(173, 216, 230, 0.8),
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 0.6)} rgba(173, 216, 230, 0.4),
        #{calc(random(1000) / 10)}vw #{calc(random(1000) / 10)}vh #{calc($size * 1)} rgba(173, 216, 230, 0.2);

    @for $i from 2 through $n {
        $shadows:
            #{$shadows},
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 0.3)}
                rgba(173, 216, 230, 0.8),
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 0.6)}
                rgba(173, 216, 230, 0.4),
            #{calc(random(1000) / 10)}vw
                #{calc(random(1000) / 10)}vh
                #{calc($size * 1)}
                rgba(173, 216, 230, 0.2);
    }

    @return $shadows;
}

$n: 18;
$size: 9px;

@for $j from 1 through 6 {
    .layer#{$j} {
        $size: calc($size - #{$j}px);
        $duration: calc(6s * #{$j});
        $n: floor(calc($n * pow(2, $j) / $j));
        position: fixed;
        width: $size;
        height: $size;
        border-radius: 50%;
        left: 0;
        top: 0;
        background-color: rgba(173, 216, 230, 0.8);
        box-shadow: getShadows($n, $size);
        animation: moveLeft $duration linear infinite;

        &::after {
            content: '';
            position: fixed;
            width: $size;
            height: $size;
            border-radius: inherit;
            left: 100vw;
            top: 0;
            background-color: rgba(173, 216, 230, 0.8);
            box-shadow: inherit;
        }
    }
}

@keyframes moveLeft {
    100% {
        transform: translateX(-100vw);
        opacity: 1;
    }

    50% {
        opacity: 0.2;
    }
}

.register_container {
    width: 100vw;
    height: 100vh;
    background: url('@/assets/images/register.jpg') no-repeat;
    background-size: cover;
    background-position: center;
    @include flex-layout(flex, center, center);
    overflow: hidden;
}

.register_form {
    position: relative;
    width: 30vw;
    min-width: 300px;
    background-color: rgba(1, 14, 31, 0.4);
    background-size: cover;
    padding: 2.5rem;
    border-radius: 0.625rem;
}

h1 {
    color: white;
    font-size: 2.5rem;
    text-align: center;
}

h2 {
    color: white;
    font-size: 1.25rem;
    margin: 1.25rem 0;
    text-align: center;
}

.register_btn {
    width: 100%;
}

.to-login {
    margin-bottom: 0;
    cursor: pointer;

    .login {
        height: 1rem;
        line-height: 1rem;
        position: absolute;
        right: 0;
        color: white;
    }

    .login:hover {
        color: rgb(255, 255, 200);
        border-bottom: 2px solid rgb(255, 255, 200);
    }
}
</style>
